#region Imported Namespaces



using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;



#endregion


namespace WtfManager.Controls
{
  ///<summary>
  /// Provides a way to choose a <see cref="DataTemplate"/> based on the data object and the data-bound element.
  ///</summary>
  public class GenericContentTemplateSelector: DataTemplateSelector
  {
    #region Fields



    private List<TemplateTypeMapping> _templateTypeMappings = new List<TemplateTypeMapping>();



    #endregion


    #region Properties/Indexers



    ///<summary>
    /// Gets or sets a list of <see cref="DataTemplate"/> to <see cref="Type"/> mappings.
    ///</summary>
    public List<TemplateTypeMapping> TemplateTypeMappings
    {
      get
      {
        return _templateTypeMappings;
      }
      set
      {
        _templateTypeMappings = value;
      }
    }



    #endregion


    #region Methods



    /// <summary>
    /// When overridden in a derived class, returns a <see cref="T:System.Windows.DataTemplate" /> based on custom logic.
    /// </summary>
    /// <returns>
    /// Returns a <see cref="T:System.Windows.DataTemplate" /> or null. The default value is null.
    /// </returns>
    /// <param name="item">
    /// The data object for which to select the template.
    /// </param>
    /// <param name="container">
    /// The data-bound object.
    /// </param>
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
      return GetItemTemplate(item);
    }



    #endregion


    ///<summary>
    /// Gets a <see cref="T:System.Windows.DataTemplate" /> for an item.
    ///</summary>
    ///<param name="item">The data object for which to select the template.</param>
    ///<returns>Returns a <see cref="T:System.Windows.DataTemplate" /> or null. The default value is null.</returns>
    public DataTemplate GetItemTemplate(object item)
    {
      if (item == null)
        return null;

      foreach (TemplateTypeMapping mapping in _templateTypeMappings)
      {
        Type type = item.GetType();
        if (type.IsSubclassOf(mapping.Type) || type == mapping.Type)
          return mapping.DataTemplate;
      }

      return null;
    }
  }
}